package com.atguigu.tingshu.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.db.sql.Order;
import com.atguigu.tingshu.account.AccountFeignClient;
import com.atguigu.tingshu.album.AlbumFeignClient;
import com.atguigu.tingshu.common.constant.KafkaConstant;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.util.DelayMsgService;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.order.OrderDerate;
import com.atguigu.tingshu.model.order.OrderDetail;
import com.atguigu.tingshu.model.order.OrderInfo;
import com.atguigu.tingshu.model.user.VipServiceConfig;
import com.atguigu.tingshu.order.helper.SignHelper;
import com.atguigu.tingshu.order.mapper.OrderDerateMapper;
import com.atguigu.tingshu.order.mapper.OrderDetailMapper;
import com.atguigu.tingshu.order.mapper.OrderInfoMapper;
import com.atguigu.tingshu.order.service.OrderInfoService;
import com.atguigu.tingshu.user.client.UserFeignClient;
import com.atguigu.tingshu.vo.account.AccountDeductVo;
import com.atguigu.tingshu.vo.order.OrderDerateVo;
import com.atguigu.tingshu.vo.order.OrderDetailVo;
import com.atguigu.tingshu.vo.order.OrderInfoVo;
import com.atguigu.tingshu.vo.order.TradeVo;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private AlbumFeignClient albumFeignClient;


    /**
     * 选择各种商品(VIP会员、专辑、声音)订单结算渲染数据汇总
     *
     * @param tradeVo 购买项目类型(1001-专辑 1002-声音 1003-vip会员)、项目ID、[购买声音数量]
     * @return OrderInfoVo
     */
    @Override
    public OrderInfoVo getOrderTradeData(Long userId, TradeVo tradeVo) {
        //1.初始化相关数据
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        //1.1 初始化相关金额“0.00” 原价、减免价、订单价
        BigDecimal originalAmount = new BigDecimal("0.00");
        BigDecimal derateAmount = new BigDecimal("0.00");
        BigDecimal orderAmount = new BigDecimal("0.00");
        //1.2 初始商品清单、优惠列表
        List<OrderDetailVo> orderDetailVoList = new ArrayList<>();
        List<OrderDerateVo> orderDerateVoList = new ArrayList<>();

        //2.处理购买类型为VIP会员
        String itemType = tradeVo.getItemType();
        if (SystemConstant.ORDER_ITEM_TYPE_VIP.equals(itemType)) {
            //2.1 远程调用"用户服务"获取套餐详情
            VipServiceConfig vipServiceConfig = userFeignClient.getVipServiceConfig(tradeVo.getItemId()).getData();
            Assert.notNull(vipServiceConfig, "套餐信息为空");

            //2.2 计算VIP套餐相关价格封装相关价格
            //2.2.1 原价
            originalAmount = vipServiceConfig.getPrice();
            //2.2.2 减免价
            derateAmount = vipServiceConfig.getDiscountPrice();
            //2.2.3 订单价=原价-减免价
            orderAmount = originalAmount.subtract(derateAmount);

            //2.3 封装商品清单明细
            OrderDetailVo orderDetailVo = new OrderDetailVo();
            orderDetailVo.setItemId(tradeVo.getItemId());
            orderDetailVo.setItemName("VIP套餐：" + vipServiceConfig.getName());
            orderDetailVo.setItemUrl(vipServiceConfig.getImageUrl());
            //商品明细中价格为 原价
            orderDetailVo.setItemPrice(originalAmount);
            orderDetailVoList.add(orderDetailVo);

            //2.4 封装商品优惠明细
            OrderDerateVo orderDerateVo = new OrderDerateVo();
            orderDerateVo.setDerateAmount(derateAmount);
            orderDerateVo.setDerateType(SystemConstant.ORDER_DERATE_VIP_SERVICE_DISCOUNT);
            orderDerateVo.setRemarks("VIP限时抢购：活动价：" + orderAmount);
            orderDerateVoList.add(orderDerateVo);

        } else if (SystemConstant.ORDER_ITEM_TYPE_ALBUM.equals(itemType)) {
            //3. 处理购买类型为专辑
            //3.1 远程调用"用户服务"判断是否已购专辑 如果已购买则抛出异常终止业务
            Long albumId = tradeVo.getItemId();
            Boolean isPaid = userFeignClient.isPaidAlbum(albumId).getData();
            Assert.state(!isPaid, "请勿重复购买");

            //3.2 远程调用用户服务获取用户是否为会员
            UserInfoVo userInfoVo = userFeignClient.getUserInfoVo(userId).getData();
            Assert.notNull(userInfoVo, "用户信息有误！");
            Boolean isVIP = false;
            if (userInfoVo.getIsVip().intValue() == 1 && userInfoVo.getVipExpireTime().after(new Date())) {
                isVIP = true;
            }

            //3.3 远程调用专辑服务获取专辑信息 得到价格、折扣
            AlbumInfo albumInfo = albumFeignClient.getAlbumInfo(albumId).getData();
            Assert.notNull(albumInfo, "专辑信息有误");

            //3.4 计算专辑相关价格封装相关价格
            //3.4.1 原价
            originalAmount = albumInfo.getPrice();
            //3.4.2 暂时让订单价=原价
            orderAmount = originalAmount;
            //3.4.3 判断是否存在普通用户折扣&是普通用户 计算普通用户价格
            BigDecimal discount = albumInfo.getDiscount();
            if (discount.intValue() != -1 && !isVIP) {
                orderAmount = originalAmount.multiply(discount).divide(BigDecimal.valueOf(10), 2, RoundingMode.HALF_UP);
            }
            //3.4.4 判断是否存在VIP用户折扣&是VIP用户 计算VIP用户价格
            BigDecimal vipDiscount = albumInfo.getVipDiscount();
            if (vipDiscount.intValue() != -1 && isVIP) {
                orderAmount = originalAmount.multiply(vipDiscount).divide(BigDecimal.valueOf(10), 2, RoundingMode.HALF_UP);
            }
            //3.4.5 计算减免价格
            if (originalAmount.compareTo(orderAmount) != 0) {
                derateAmount = originalAmount.subtract(orderAmount);
                //3.6 封装商品优惠明细
                OrderDerateVo orderDerateVo = new OrderDerateVo();
                orderDerateVo.setDerateType(SystemConstant.ORDER_DERATE_ALBUM_DISCOUNT);
                orderDerateVo.setDerateAmount(derateAmount);
                orderDerateVo.setRemarks("专辑折扣价：" + orderAmount);
                orderDerateVoList.add(orderDerateVo);

            }
            //3.5 封装商品清单明细
            OrderDetailVo orderDetailVo = new OrderDetailVo();
            orderDetailVo.setItemId(albumId);
            orderDetailVo.setItemName("专辑：" + albumInfo.getAlbumTitle());
            orderDetailVo.setItemUrl(albumInfo.getCoverUrl());
            orderDetailVo.setItemPrice(originalAmount);
            orderDetailVoList.add(orderDetailVo);

        } else if (SystemConstant.ORDER_ITEM_TYPE_TRACK.equals(itemType)) {
            //4. TODO 处理购买类型为声音

            //4.1 远程调用专辑服务获取待购声音列表
            Long trackId = tradeVo.getItemId();
            List<TrackInfo> trackInfoList = albumFeignClient.getWaitBuyTrackInfoList(trackId, tradeVo.getTrackCount()).getData();
            Assert.notNull(trackInfoList, "无符合要求待结算声音列表");

            //4.2 远程调用专辑服务获取专辑信息得到声音单价
            AlbumInfo albumInfo = albumFeignClient.getAlbumInfo(trackInfoList.get(0).getAlbumId()).getData();
            BigDecimal price = albumInfo.getPrice();

            //4.3 计算声音相关价格封装相关价格
            originalAmount = price.multiply(BigDecimal.valueOf(trackInfoList.size()));
            orderAmount = originalAmount;

            //4.4 封装商品清单明细
            orderDetailVoList = trackInfoList.stream()
                    .map(trackInfo -> {
                        OrderDetailVo orderDetailVo = new OrderDetailVo();
                        orderDetailVo.setItemId(trackInfo.getId());
                        orderDetailVo.setItemName(trackInfo.getTrackTitle());
                        orderDetailVo.setItemUrl(trackInfo.getCoverUrl());
                        orderDetailVo.setItemPrice(price);
                        return orderDetailVo;
                    }).collect(Collectors.toList());
        }

        //5.封装订单VO中相关信息
        //5.1  价格信息
        orderInfoVo.setOriginalAmount(originalAmount);
        orderInfoVo.setDerateAmount(derateAmount);
        orderInfoVo.setOrderAmount(orderAmount);
        //5.2 商品清单及优惠清单
        orderInfoVo.setOrderDetailVoList(orderDetailVoList);
        orderInfoVo.setOrderDerateVoList(orderDerateVoList);
        //5.3 TODO 其他信息”包含：流水号、项目类型、时间戳及签名
        //5.3 封装购买项目类型
        orderInfoVo.setItemType(tradeVo.getItemType());
        //5.4封装本次订单VO流水号
        //5.4.1 生成本次订单用户流水号Key
        String key = RedisConstant.ORDER_TRADE_NO_PREFIX + userId;
        //5.4.2 生成流水号
        String tradeNo = IdUtil.fastSimpleUUID();
        //5.4.3 将流水号存入Redis设置过期时间为5分钟
        redisTemplate.opsForValue().set(key, tradeNo, RedisConstant.ORDER_TRADE_EXPIRE, TimeUnit.MINUTES);
        //5.4.4 封装订单VO中流水号信息
        orderInfoVo.setTradeNo(tradeNo);
        //5.5封装本次订单信息产生签名值
        //5.5.1 封装订单信息VO中时间戳
        orderInfoVo.setTimestamp(DateUtil.current());
        //5.5.2 将订单VO信息转为Map TODO 将渲染订单确认页面无法封装付款方式payWay;排除掉
        Map<String, Object> paramsMap = BeanUtil.beanToMap(orderInfoVo, false, true);
        //5.5.3 对本次订单vo信息进行签名
        String sign = SignHelper.getSign(paramsMap);
        orderInfoVo.setSign(sign);
        return orderInfoVo;
    }

    @Autowired
    private AccountFeignClient accountFeignClient;

    @Autowired
    private DelayMsgService delayMsgService;

    /**
     * 订单提交-支付方式选择（1.微信支付 2.余额支付）
     * 核心业务：
     * 1. 保存订单
     * 2. 扣减余额
     * 3. 虚拟物品发货
     *
     * @param userId      用户ID
     * @param orderInfoVo 订单VO信息
     * @return
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public Map<String, String> submitOrder(Long userId, OrderInfoVo orderInfoVo) {
        //1.业务校验：验证流水号避免用户利用业务回退导致订单重复提交
        //1.1 构建当前用户订单流水号Key查询Redis中流水号
        String key = RedisConstant.ORDER_TRADE_NO_PREFIX + userId;
        //1.2 如果Redis中存储流水号跟前端提交一致 通过校验，立即将Redis中流水删除 反之抛出异常终止业务
        String scriptText = "if redis.call(\"get\",KEYS[1]) == ARGV[1]\n" +
                "then\n" +
                "    return redis.call(\"del\",KEYS[1])\n" +
                "else\n" +
                "    return 0\n" +
                "end";
        DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>(scriptText, Boolean.class);
        Boolean flag = (Boolean) redisTemplate.execute(redisScript, Arrays.asList(key), orderInfoVo.getTradeNo());
        if (!flag) {
            throw new GuiguException(400, "流水号验证失败,请重试");
        }


        //2.业务校验：验证签名 避免用户恶意篡改订单信息
        //2.1 将订单VO转为Map TODO 由于订单确认页生成签名使用payWay属性，验签确保参数中没有payWay
        Map<String, Object> mapParams = BeanUtil.beanToMap(orderInfoVo);
        mapParams.remove("payWay");
        //2.2 验证签名
        SignHelper.checkSign(mapParams);
        //3.保存订单及订单明细
        OrderInfo orderInfo = this.saveOrderInfo(userId, orderInfoVo);
        //4. 处理用户选择支付方式为：余额  扣减余额 及 虚拟物品发货
        String payWay = orderInfoVo.getPayWay();
        if (SystemConstant.ORDER_PAY_ACCOUNT.equals(payWay)) {
            //4.1 远程调用账户服务完成余额扣减
            //4.1.1 准备扣减余额远程调用所需入参对象
            AccountDeductVo accountDeductVo = new AccountDeductVo();
            accountDeductVo.setOrderNo(orderInfo.getOrderNo());
            accountDeductVo.setUserId(orderInfo.getUserId());
            accountDeductVo.setAmount(orderInfo.getOrderAmount());
            accountDeductVo.setContent(orderInfo.getOrderTitle());
            //4.1.2 发送Feign远程调用
            Result result = accountFeignClient.checkAndDeduct(accountDeductVo);
            //4.1.3 因为存在全局异常处理，导致及时目标服务发生异常Feign接口正常响应Result(业务状态码非200)
            if (!ResultCodeEnum.SUCCESS.getCode().equals(result.getCode())) {
                throw new GuiguException(400, "余额扣减失败！");
            }
            //4.2 余额扣减成功后，该笔订单支付状态改为：已支付
            orderInfo.setOrderStatus(SystemConstant.ORDER_STATUS_PAID);
            orderInfoMapper.updateById(orderInfo);

            //4.3 远程调用用户服务完成虚拟物品发货
            //4.3.1 准备虚拟物品发货远程调用所需入参对象
            UserPaidRecordVo userPaidRecordVo = new UserPaidRecordVo();
            userPaidRecordVo.setOrderNo(orderInfo.getOrderNo());
            userPaidRecordVo.setUserId(orderInfo.getUserId());
            userPaidRecordVo.setItemType(orderInfo.getItemType());
            //获取购买项目ID集合
            List<Long> itemIdList =
                    orderInfoVo.getOrderDetailVoList()
                            .stream().map(OrderDetailVo::getItemId)
                            .collect(Collectors.toList());
            userPaidRecordVo.setItemIdList(itemIdList);

            //4.3.2 发送Feign远程调用
            result = userFeignClient.savePaidRecord(userPaidRecordVo);
            //4.3.3 因为存在全局异常处理，导致及时目标服务发生异常Feign接口正常响应Result(业务状态码非200)
            if (!ResultCodeEnum.SUCCESS.getCode().equals(result.getCode())) {
                throw new GuiguException(400, "发货失败！");
            }
        } else if (SystemConstant.ORDER_PAY_WAY_WEIXIN.equals(payWay)) {
            //5. 处理用户选择支付方式为：微信  采用延迟任务 延迟关单 TODO 需要修改为1小时
            delayMsgService.sendDelayMsg(KafkaConstant.QUEUE_ORDER_CANCEL, orderInfo.getId().toString(), 5L, TimeUnit.MINUTES);
        }
        //6.返回对象封装订单编号
        Map<String, String> map = new HashMap<>();
        map.put("orderNo", orderInfo.getOrderNo());
        return map;
    }

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private OrderDerateMapper orderDerateMapper;

    /**
     * 保存订单 及订单明细，优惠列表
     *
     * @param userId      用户ID
     * @param orderInfoVo 订单VO信息
     * @return 保存后订单对象
     */
    @Override
    public OrderInfo saveOrderInfo(Long userId, OrderInfoVo orderInfoVo) {
        //1.保存订单
        //1.1 将订单VO中信息拷贝到PO对象中
        OrderInfo orderInfo = BeanUtil.copyProperties(orderInfoVo, OrderInfo.class);
        //1.2 封装其他对象属性
        //1.2.1 设置用户ID
        orderInfo.setUserId(userId);
        //1.2.2 设置订单状态
        orderInfo.setOrderStatus(SystemConstant.ORDER_STATUS_UNPAID);
        //1.2.3 设置订单编号 商户侧确保全局唯一 规则：年月日+雪花算法
        String orderNo = DateUtil.today().replaceAll("-", "") + IdUtil.getSnowflakeNextId();
        orderInfo.setOrderNo(orderNo);
        //1.2.4 设置订单商品标题
        List<OrderDetailVo> orderDetailVoList = orderInfoVo.getOrderDetailVoList();
        if (CollectionUtil.isNotEmpty(orderDetailVoList)) {
            String itemName = orderDetailVoList.get(0).getItemName();
            orderInfo.setOrderTitle(itemName);
        }
        //1.3 保存订单得到订单ID
        orderInfoMapper.insert(orderInfo);
        Long orderId = orderInfo.getId();

        //2.保存订单明细
        if (CollectionUtil.isNotEmpty(orderDetailVoList)) {
            //2.1 将订单明细VO集合转为PO 关联订单ID
            orderDetailVoList.stream().forEach(orderDetailVo -> {
                OrderDetail orderDetail = BeanUtil.copyProperties(orderDetailVo, OrderDetail.class);
                orderDetail.setOrderId(orderId);
                //2.2 保存订单明细
                orderDetailMapper.insert(orderDetail);
                //TODO 如果进行批量新增 选择注入业务接口Iservice中saveBatch批量保存
            });
        }
        //3.保存订单优惠列表
        List<OrderDerateVo> orderDerateVoList = orderInfoVo.getOrderDerateVoList();
        if (CollectionUtil.isNotEmpty(orderDerateVoList)) {
            orderDerateVoList.stream().forEach(orderDerateVo -> {
                OrderDerate orderDerate = BeanUtil.copyProperties(orderDerateVo, OrderDerate.class);
                orderDerate.setOrderId(orderId);
                orderDerateMapper.insert(orderDerate);
            });
        }
        return orderInfo;
    }

    /**
     * 根据订单编号查询订单信息（包含明细）
     *
     * @param orderNo
     * @return
     */
    @Override
    public OrderInfo getOrderInfo(String orderNo) {
        //1.查询订单信息
        LambdaQueryWrapper<OrderInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderInfo::getOrderNo, orderNo);
        OrderInfo orderInfo = orderInfoMapper.selectOne(queryWrapper);
        if (orderInfo != null) {
            //2.查询订单商品明细
            LambdaQueryWrapper<OrderDetail> orderDetailLambdaQueryWrapper = new LambdaQueryWrapper<>();
            orderDetailLambdaQueryWrapper.eq(OrderDetail::getOrderId, orderInfo.getId());
            List<OrderDetail> orderDetailList = orderDetailMapper.selectList(orderDetailLambdaQueryWrapper);
            orderInfo.setOrderDetailList(orderDetailList);
        }
        return orderInfo;
    }

    /**
     * 查询当前用户订单列表
     *
     * @param userId
     * @param pageInfo
     * @return
     */
    @Override
    public Page<OrderInfo> getOrderByPage(Long userId, Page<OrderInfo> pageInfo) {
        //1.调用持久层动态SQL查询订单及订单明细
        pageInfo = orderInfoMapper.getOrderByPage(pageInfo, userId);
        return pageInfo;
    }

    /**
     * 用户微信支付成功后，修改订单支付状态且完成虚拟物品发货
     *
     * @param orderNo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void orderPaySuccess(String orderNo) {
        //1.更新订单状态：已支付
        LambdaUpdateWrapper<OrderInfo> updateWrapper = new LambdaUpdateWrapper<>();
        //设置修改条件 where 部分
        updateWrapper.eq(OrderInfo::getOrderNo, orderNo);
        //设置更新字段 set 部分
        updateWrapper.set(OrderInfo::getOrderStatus, SystemConstant.ORDER_STATUS_PAID);
        this.update(updateWrapper);

        //2.远程调用用户服务-虚拟物品发货 订单中可以获取到购买商品ID
        //2.1 构建发货VO对象
        //2.1.1 查询订单信息
        LambdaQueryWrapper<OrderInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderInfo::getOrderNo, orderNo);
        OrderInfo orderInfo = this.getOne(queryWrapper);
        UserPaidRecordVo userPaidRecordVo = new UserPaidRecordVo();
        userPaidRecordVo.setOrderNo(orderNo);
        userPaidRecordVo.setUserId(orderInfo.getUserId());
        userPaidRecordVo.setItemType(orderInfo.getItemType());
        //2.1.2 根据订单ID查询订单明细获取购买项目ID列表
        LambdaQueryWrapper<OrderDetail> orderDetailLambdaQueryWrapper = new LambdaQueryWrapper<>();
        orderDetailLambdaQueryWrapper.eq(OrderDetail::getOrderId, orderInfo.getId());
        orderDetailLambdaQueryWrapper.select(OrderDetail::getItemId);
        List<OrderDetail> orderDetailList = orderDetailMapper.selectList(orderDetailLambdaQueryWrapper);
        List<Long> itemIdList = orderDetailList.stream().map(OrderDetail::getItemId).collect(Collectors.toList());
        userPaidRecordVo.setItemIdList(itemIdList);
        //2.2 远程调用用户服务虚拟物品发货
        Result result = userFeignClient.savePaidRecord(userPaidRecordVo);

        //2.3 判断远程调用结果对象业务状态码是否为200
        if (!ResultCodeEnum.SUCCESS.getCode().equals(result.getCode())) {
            throw new GuiguException(500, "虚拟物品发货异常");
        }
    }


    @Autowired
    private RedissonClient redissonClient;


    /**
     * 监听订单取消消息
     */
    @PostConstruct
    public void listenCanalOrderMsg() {
        //1.获取阻塞队列对象
        RBlockingQueue<String> blockingQueue = redissonClient.getBlockingQueue(KafkaConstant.QUEUE_ORDER_CANCEL);
        //2.开启单独线程-专门负责监听阻塞队列延迟消息
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        //3.根据监听到订单ID判断订单支付状态，根据状态选择关闭订单
        executorService.submit(() -> {
            while (true) {
                String poll = blockingQueue.poll(1, TimeUnit.SECONDS);
                if (StringUtils.isNotBlank(poll)) {
                    log.info("[订单服务]监听延迟关闭消息：{},判断是否需要关单", poll);
                    this.orderCancel(Long.valueOf(poll));
                }
            }
        });
    }


    /**
     * 执行关单业务方法
     *
     * @param orderId
     */
    public void orderCancel(Long orderId) {
        //1.根据订单ID查询订单信息得到支付状态
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        //2.如果订单依然是未支付，将订单状态改为：关闭
        if (orderInfo != null && SystemConstant.ORDER_STATUS_UNPAID.equals(orderInfo.getOrderStatus())) {
            orderInfo.setOrderStatus(SystemConstant.ORDER_STATUS_CANCEL);
            orderInfoMapper.updateById(orderInfo);
        }
    }
}
